<script setup lang="ts">
import { computed, ref } from 'vue'
import {
  NScrollbar,
  NInput,
  NIcon,
  NButton,
  NModal,
  NSpace,
  NTag
} from 'naive-ui'
import {
  Search20Regular,
  DocumentEdit20Regular
} from '@vicons/fluent'
import NodeService from '@/services/node.service'
import NodeEditor from '@/components/node-editor.vue'
import { NodeItem } from '@/types/node'

const dragImgRef = ref<HTMLImageElement>()
const editorRef = ref<InstanceType<typeof NodeEditor>>()
const nodeService = new NodeService()
const nodes = ref<NodeItem[]>([])
const innerNodes = nodeService.inner_nodes as NodeItem[]
const nodeList = computed(() => [...innerNodes, ...nodes.value])
const showEditor = ref(false)
const node = ref<NodeItem>()
nodeService.load().then(res => {
  nodes.value = res
})

function onDragStart (evt: DragEvent, node: NodeItem) {
  evt.dataTransfer?.setDragImage(dragImgRef.value!, 12, 12)
  evt.dataTransfer?.setData('Text', JSON.stringify(node))
  console.log(node)
}
function onNodeEdit (n: NodeItem) {
  node.value = n
  showEditor.value = true
}
function onNodeCancel () {
  showEditor.value = false
}
function onNodeSave () {
  const json = editorRef.value?.json()
  if (!json) {
    return
  }
  const index = nodes.value.findIndex(v => v.id === node.value?.id)
  if (index < 0) {
    return
  }
  nodes.value[index] = json
  nodeService.save(nodes.value)
  showEditor.value = false
  editorRef.value?.reset()
}

defineExpose({
  add (node: NodeItem | undefined) {
    if (!node) {
      return
    }
    const exists = nodes.value.find(v => v.id === node.id)
    if (exists) {
      node.id += '' + Math.round(Math.random() * 100)
    }
    nodes.value.push(node)
    nodeService.save(nodes.value)
  },
  search () {

  }
})
</script>

<template>
  <div class="nodes">
    <div class="placeholder" v-if="nodes.length < 1">
      请增加节点
    </div>
    <n-input v-if="nodes.length > 0" :bordered="false" :round="false" placeholder="输入关键字筛选">
      <template #suffix>
        <n-icon size="20" :component="Search20Regular" />
      </template>
    </n-input>
    <n-scrollbar v-if="nodes.length > 0">
      <a class="node" v-for="node of nodeList" :key="node.name" draggable="true" @dragstart="evt => onDragStart(evt, node)">
        <span>{{ node.name }}</span>
        <n-space :size="8">
          <n-tag size="small" type="info" :bordered="false">输入: {{ node.inputs.length }}</n-tag>
          <n-tag size="small" type="info" :bordered="false">输出: {{ node.outputs.length }}</n-tag>
        </n-space>
        <n-button v-if="!node.type" text @click="onNodeEdit(node)">
          <n-icon size="18"><DocumentEdit20Regular /></n-icon>
        </n-button>
      </a>
    </n-scrollbar>
    <!-- 编辑 -->
    <n-modal class="node-editor-modal" v-model:show="showEditor" preset="card" :close-on-esc="false" title="修改节点"
      :mask-closable="false" :closable="false" :segmented="{
      content: 'soft',
      footer: 'soft'
    }">
      <NodeEditor ref="editorRef" v-model="node" />
      <template #footer>
        <n-button text type="warning" @click="onNodeCancel">取消</n-button>
        <n-button type="primary" @click="onNodeSave">保存</n-button>
      </template>
    </n-modal>
    <img ref="dragImgRef" class="drag-image" src="../assets/code.svg">
  </div>
</template>
<style scoped lang="less">
.nodes {
  display: flex;
  flex-direction: column;
  align-items: center;
  .n-input {
    --n-border-radius: 0 !important;
    --n-padding-right: 5px !important;
  }
  .placeholder {
    opacity: 0.5;
    padding: 12px;
  }
  .node {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    position: relative;
    .n-space {
      font-size: 12px;
      margin-left: auto;
      .n-tag {
        background: transparent;
        --n-padding: 0 !important;
        opacity: 0.75;
      }
    }
    button {
      position: absolute;
      right: 0;
      opacity: 0;
      pointer-events: none;
      width: 36px;
      height: 100%;
      background-color: #333333;
    }
    &:hover {
      background-color: #FFFFFF08;
      button {
        opacity: 1;
        pointer-events: all;
      }
    }
  }
  .drag-image {
    position: fixed;
    top: 0;
    left: -1000px;
    height: 24px;
  }
}
</style>
